package com.scs.application.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.consts.Const;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.Md5Utils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilCommon;
import com.scs.application.modules.sys.entity.InitDataLog;
import com.scs.application.modules.sys.service.InitDataLogService;
import com.scs.application.modules.sys.service.InitDataService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Comparator;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class InitDataServiceImpl implements InitDataService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private TransactionTemplate transactionTemplate;


    @Autowired
    private InitDataLogService initDataLogService;

    /**
    * @Description： 是否升级流程
    */
    @Value("${init-data.inactive-sysflow:true}")
    String inactiveSysflow;
    /**
    * @Description： 是否升级报表
    */
    @Value("${init-data.inactive-report:true}")
    String inactiveReport;

    @Override
    public String getList() {
        return FileUtils.readFileStore(Const.getInitDataSqlSrc());
        //        return FileUtils.readFile(Const.INIT_DATA_SQL_SRC);
    }

    @Override
    public void save(String str) {


        JSONObject jsonObject = JSONObject.parseObject(str);
        FileUtils.writeTxtFile(Const.INIT_DATA_SQL_SRC, JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat));
    }

    @Override
    public void execute(String fileName) {
        JSONObject sqlStore = JSONObject.parseObject(getList());
        JSONArray items = sqlStore.getJSONArray("items");
        Integer sqlId = 0;
        String sql=null;
        String checkCode,tables,type;

        //根据ID升序排序
        items.sort(Comparator.comparing(obj -> ((JSONObject) obj).getBigDecimal("id")));

//        long sysUserCount = jdbcTemplate.queryForObject("SELECT count(1) FROM sys_user ",Long.class);

        for (int i = 0; i < items.size(); i++) {
            JSONObject item = items.getJSONObject(i);
            sqlId = item.getInteger("id");
            tables = item.getString("tables");
            type = item.getString("type");
            if (StringUtils.isNotBlank(fileName) && !fileName.equals(tables)) continue;

            //未拆分的
            if (item.containsKey("sql")) {
                sql = item.getString("sql");
            } else { //已拆分的则取对应文件里面的
                List<String> lines = null;
                try {
                    if (StringUtils.isNotBlank(tables)) {
                        lines = FileUtils.readFileLinesStore("init-data/" + tables + ".txt");
                        if (lines != null && lines.size() > 0 && StringUtils.isNotBlank(lines.get(0))) {
                            sql = StringUtils.join(lines, "\n");
                        }
                    }
                } catch (Exception e) {
                    logger.error("execute.error", tables);
                    logger.error("execute.error", e);
//                    throw new BusinessException("读取数据文件失败，原因:%s",e.getMessage());
                }
            }
            sql= UtilCommon.getStr(sql,"");

            if (tables.toLowerCase().equals("sys_flow") && !"false".equals(inactiveSysflow)){
                log.info("-- 不执行初始化数据:sys_flow--");
                continue;
            };
            if (
                    (
                            tables.toLowerCase().equals("report_config")
                    ||
                            tables.toLowerCase().equals("report_grid_field")
                    ||
                            tables.toLowerCase().equals("report_chart_field")
                    )

                    && !"false".equals(inactiveReport)){
                log.info("-- 不执行初始化数据:report--");
                continue;
            };
            checkCode = Md5Utils.md5(sql);


//            if (sysUserCount > 0) {
//                /**
//                 * @若没有拆分文件的执行记录，不需要执行初始化sql
//                 * @存在的问题 若拆分过，并且拆分文件进行了修改，则第一启动会丢失配置，但是第二次启动就可以正常了
//                 *       怎么判断都会有问题，这里使用不容易出错的判断。如果第一次拆分更新项目，并且有sql文件进行了改动，这时手动全部执行一次就可以了
//                 * @Date 2021/5/11
//                 */
//                List<InitDataLog> initDataLogSplitList = initDataLogService.list(Wrappers.<InitDataLog>query()
//                        .eq("sql_id", sqlId)
//                        .eq("file_name", tables));
//                if (initDataLogSplitList == null || initDataLogSplitList.size()  < 1) {
//                    InitDataLog initDataLogSplit = new InitDataLog().setSqlId(sqlId)
//                            .setSqls(sql)
//                            .setTableNames(item.getString("tables"))
//                            .setDescription(StringUtils.defaultIfBlank(item.getString("description"), item.getString("tables")))
//                            .setCheckCode(checkCode)
//                            .setExecTime(new Date()).setFileName(tables);
//                    initDataLogSplit.setExecCode(0);
//                    initDataLogService.save(initDataLogSplit);
//                    continue;
//                }
//            }

            InitDataLog initDataLog = initDataLogService.getOne(Wrappers.<InitDataLog>query()
                    .eq("sql_id", sqlId)
                    .eq("check_code", checkCode) .eq("file_name", tables)
                    .eq("exec_code", 0));
            //logger.info("InitDataServiceImpl.execute.sql_id",sqlId );
            if (initDataLog == null||"view".equals(type)) {
                if(initDataLog == null){
                    initDataLog = new InitDataLog();
                }
                initDataLog.setSqlId(sqlId)
                        .setSqls(sql)
                        .setTableNames(item.getString("tables"))
                        .setDescription(StringUtils.defaultIfBlank(item.getString("description"), item.getString("tables")))
                        .setCheckCode(checkCode)
                        .setExecTime(new Date()).setFileName(tables);
                String finalSql = sql.replaceAll("`fortec-bm`.","");
                if(org.apache.commons.lang3.StringUtils.isBlank(finalSql) || finalSql.length() < 6) continue;
                try{
                    transactionTemplate.execute(transactionStatus -> {
                        jdbcTemplate.execute(finalSql);
                        return null;
                    });
                    log.info("Execute success, sqlId:" + sqlId);
                    initDataLog.setExecCode(0);

                    initDataLogService.saveOrUpdate(initDataLog);
                }catch (Exception e){
                    log.error(String.valueOf(e));
                }


            }
        }
    }

}
